package com.snail.common.core.utils;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSONObject;
import com.snail.common.core.exception.ServiceException;
import com.snail.common.core.utils.bean.BeanValidators;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Path;
import javax.validation.Validator;
import java.util.List;
import java.util.Set;

/**
 * @Description: 数据校验工具类
 * @Author: Snail
 * @CreateDate: 2023/8/16 15:54
 * @Version: V1.0
 */
public class ValidationUtils {

    /**
     * 校验对象是否为空
     *
     * @param obj      对象
     * @param errorMsg 错误信息
     * @return 结果
     */
    public static String isNull(Object obj, String errorMsg) {
        if (obj == null) {
            return errorMsg;
        }
        //字符串
        if (obj instanceof String && StringUtils.isEmpty(obj.toString())) {
            return errorMsg;
        }
        return "";
    }

    /**
     * 校验对象是否为空
     *
     * @param obj      对象
     * @param errorMsg 错误信息
     * @return 结果
     */
    public static String isNotNull(Object obj, String errorMsg) {
        if (obj == null) {
            return "";
        }
        //字符串
        if (obj instanceof String && StringUtils.isNotEmpty(obj.toString())) {
            return errorMsg;
        }
        return errorMsg;
    }

    /**
     * 校验对象是否为空
     *
     * @param obj      对象
     * @param errorMsg 错误信息提示
     * @param error    错误信息
     * @return 结果
     */
    public static void isNotNull(Object obj, String errorMsg, StringBuffer error) {
        error.append(isNotNull(obj, errorMsg));
    }

    /**
     * 校验对象是否为空
     *
     * @param obj      对象
     * @param errorMsg 错误信息提示
     * @param error    错误信息
     */
    public static void isNull(Object obj, String errorMsg, StringBuffer error) {
        error.append(isNull(obj, errorMsg));
    }

    /**
     * 判断是否为true
     *
     * @param isTrue   是否为true
     * @param errorMsg 错误提示信息
     * @return 结果
     */
    public static String isTrue(boolean isTrue, String errorMsg) {
        if (isTrue) {
            return errorMsg;
        }
        return "";
    }

    /**
     * 判断是否为true
     *
     * @param isTrue   是否为true
     * @param errorMsg 错误提示信息
     * @param error    错误信息
     */
    public static void isTrue(boolean isTrue, String errorMsg, StringBuffer error) {
        error.append(isTrue(isTrue, errorMsg));
    }


    /**
     * 根据属性的注解进行校验
     *
     * @param clazz 反射类
     */
    public static void checkProperty(Validator validator, Object object, List<String> excludeFiled, Class<?> clazz, StringBuffer error) {
        try {
            BeanValidators.validateWithException(validator, object);
        } catch (ConstraintViolationException e) {
            Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
            for (ConstraintViolation<?> constraintViolation : constraintViolations) {
                Path propertyPath = constraintViolation.getPropertyPath();
                if (!CollectionUtil.contains(excludeFiled, propertyPath.toString())) {
                    error.append(constraintViolation.getMessageTemplate()).append("!");
                }
            }
        }
    }

    /**
     * 必填校验
     *
     * @param object  校验对象
     * @param msg     提示信息
     * @param builder 封装提示信息
     */
    public static void required(Object object, String msg, StringBuilder builder) {
        if (object == null) {
            builder.append(msg);
        }
    }

    /**
     * 必填校验
     *
     * @param str     校验字符
     * @param msg     提示信息
     * @param builder 封装提示信息
     */
    public static void required(String str, String msg, StringBuilder builder) {
        if (StringUtils.isBlank(str)) {
            builder.append(msg);
        }
    }

    /**
     * 必填校验
     *
     * @param condition 条件
     * @param msg       提示信息
     * @param builder   封装提示信息
     */
    public static void required(boolean condition, String msg, StringBuilder builder) {
        if (condition) {
            builder.append(msg);
        }
    }

    /**
     * 必填校验
     *
     * @param condition 条件
     * @param errorKey  错误信息key
     * @param errorVal  提示信息
     * @param error     封装提示信息
     */
    public static void required(boolean condition, JSONObject error, String errorKey, Object errorVal) {
        if (condition) {
            error.put(errorKey, errorVal);
        }
    }

    /**
     * 必填校验
     *
     * @param condition 条件
     * @param errorKey  错误信息key
     * @param error     封装提示信息
     */
    public static void required(boolean condition, JSONObject error, String errorKey) {
        if (condition) {
            error.put(errorKey, "不能为空!");
        }
    }


    /**
     * 必填校验
     *
     * @param condition 条件
     * @param errorKey  错误信息key
     * @param error     封装提示信息
     */
    public static void dataError(boolean condition, JSONObject error, String errorKey) {
        if (condition) {
            error.put(errorKey, "类型错误!");
        }
    }

    /**
     * 必填校验
     *
     * @param str      字符
     * @param errorKey 错误信息key
     * @param errorVal 提示信息
     * @param error    封装提示信息
     */
    public static void required(String str, JSONObject error, String errorKey, Object errorVal) {
        if (StringUtils.isBlank(str)) {
            error.put(errorKey, errorVal);
        }
    }

    /**
     * 必填校验
     *
     * @param str      字符
     * @param errorKey 错误信息key
     * @param error    封装提示信息
     */
    public static void required(String str, JSONObject error, String errorKey) {
        if (StringUtils.isBlank(str)) {
            error.put(errorKey, "不能为空!");
        }
    }

    /**
     * 必填校验
     *
     * @param obj      校验对象
     * @param errorKey 错误信息key
     * @param errorVal 提示信息
     * @param error    封装提示信息
     */
    public static void required(Object obj, JSONObject error, String errorKey, Object errorVal) {
        if (obj == null) {
            error.put(errorKey, errorVal);
        }
    }

    /**
     * 必填校验
     *
     * @param obj      校验对象
     * @param errorKey 错误信息key
     * @param error    封装提示信息
     */
    public static void required(Object obj, JSONObject error, String errorKey) {
        if (obj == null) {
            error.put(errorKey, "不能为空!");
        }
    }

    /**
     * 校验信息不为空时抛出业务异常
     *
     * @param condition 条件
     * @param msg       异常信息
     */
    public static void throwException(boolean condition, StringBuilder msg) {
        if (condition) {
            throw new ServiceException(msg.toString());
        }
    }

    /**
     * 校验信息不为空时抛出业务异常
     *
     * @param condition 条件
     * @param msg       异常信息
     */
    public static void throwException(boolean condition, String msg) {
        if (condition) {
            throw new ServiceException(msg);
        }
    }

    /**
     * 校验不能同时同时为空
     *
     * @param condition1 条件1
     * @param condition2 条件2
     * @param msg        提示消息
     */
    public static void throwException(boolean condition1, boolean condition2, String msg) {
        if (condition1 && condition2) {
            throw new ServiceException(msg);
        }
    }


}
